package com.hmy.finance.service.receipt.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hmy.ccp.error.exception.HMYRuntimeException;
import com.hmy.finance.api.bo.core.response.customerContactorBalance.ContactorBalanceAccountInfoResponse;
import com.hmy.finance.api.bo.core.response.customerContactorBalance.CustomerContactorBalanceAccountInfoResponse;
import com.hmy.finance.api.common.enums.receipt.AccountStatusEnum;
import com.hmy.finance.dal.dos.ContactorsTotalArrearsAmountDo;
import com.hmy.finance.dal.mapper.ReceivableInventoryMapper;
import com.hmy.finance.dal.mapper.receipt.CustomerContactorBalanceAccountMapper;
import com.hmy.finance.dal.po.receipt.CustomerContactorBalanceAccountPo;
import com.hmy.finance.service.receipt.CustomerBalanceAccountProvideService;
import com.hmy.finance.service.receipt.CustomerContactorBalanceAccountService;
import com.hmy.finance.service.receipt.dto.CustomerContactorBalanceAccountInfoDto;
import com.hmy.finance.service.receipt.dto.contactorAccount.ContactorBalanceQueryDto;
import com.hmy.finance.service.receipt.dto.contactorAccount.ContactorInitialAccountDto;
import com.hmy.finance.service.receipt.dto.customerAccount.CustomerBalanceQueryDto;
import com.hmy.finance.service.receipt.dto.customerAccount.CustomerInitialAccountDto;
import com.hmy.finance.service.receipt.rdto.contactorAccount.ContactorBalanceQueryRdto;
import com.hmy.finance.service.receipt.rdto.contactorAccount.ContactorInitialAccountRdto;
import com.hmy.finance.service.receipt.rdto.customerAccount.CustomerBalanceQueryRdto;
import com.hmy.finance.service.receipt.rdto.customerAccount.CustomerInitialAccountRdto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author loqel
 * @description 针对表【customer_contactor_balance_account(客户余额账户)】的数据库操作Service实现
 * @createDate 2024-04-11 11:33:19
 */
@Slf4j
@Service
public class CustomerContactorBalanceAccountServiceImpl implements CustomerContactorBalanceAccountService {

    @Resource
    private ReceivableInventoryMapper receivableInventoryMapper;
    @Resource
    private CustomerBalanceAccountProvideService customerBalanceAccountProvideService;
    @Resource
    private CustomerContactorBalanceAccountMapper customerContactorBalanceAccountMapper;

    /**
     * 查询客户联系人账户信息
     */
    @Override
    public CustomerContactorBalanceAccountInfoResponse queryCustomerContactorBalanceAccountInfo(CustomerContactorBalanceAccountInfoDto customerContactorBalanceAccountInfoDto) {
        log.info("CustomerContactorBalanceAccountService#queryCustomerContactorBalanceAccountInfo request:{}", JSON.toJSON(customerContactorBalanceAccountInfoDto));
        /*查询联系人账户信息*/
        List<Long> contactorIds = customerContactorBalanceAccountInfoDto.getCustomerContactorIds();
        LambdaQueryWrapper<CustomerContactorBalanceAccountPo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CustomerContactorBalanceAccountPo::getCustomerId, customerContactorBalanceAccountInfoDto.getCustomerId());
        queryWrapper.in(CustomerContactorBalanceAccountPo::getContactorId, contactorIds);
        queryWrapper.eq(CustomerContactorBalanceAccountPo::getIsDeleted, 0);
        List<CustomerContactorBalanceAccountPo> contactorBalanceAccountInfoPos = customerContactorBalanceAccountMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(contactorBalanceAccountInfoPos)) {
            throw new HMYRuntimeException(506800004);
        }
        String customerName = contactorBalanceAccountInfoPos.get(0).getCustomerName();
        customerContactorBalanceAccountInfoDto.setCustomerName(customerName);

        /*查询该客户联系人的总欠款金额*/
        List<ContactorsTotalArrearsAmountDo> contactorsTotalArrearsAmountDos = receivableInventoryMapper.selectContactorsContractTotalArrearsAmount(customerContactorBalanceAccountInfoDto.getCustomerId(), contactorIds);
        if (CollectionUtil.isEmpty(contactorsTotalArrearsAmountDos)) {
            throw new HMYRuntimeException(506800005);
        }

        CustomerContactorBalanceAccountInfoResponse response = new CustomerContactorBalanceAccountInfoResponse();
        response.setCustomerId(customerContactorBalanceAccountInfoDto.getCustomerId());
        response.setCustomerName(customerContactorBalanceAccountInfoDto.getCustomerName());
        List<ContactorBalanceAccountInfoResponse> contactorBalanceAccountInfos = new ArrayList<>();//联系人账户信息
        contactorIds.forEach(contactorId -> {
            ContactorBalanceAccountInfoResponse contactorBalanceAccountInfo = new ContactorBalanceAccountInfoResponse();
            if (contactorBalanceAccountInfoPos.stream().anyMatch(c -> c.getContactorId().equals(contactorId))) {
                CustomerContactorBalanceAccountPo contactorBalanceAccountPo = contactorBalanceAccountInfoPos.stream().filter(c -> c.getContactorId().equals(contactorId)).findFirst().get();
                contactorBalanceAccountInfo.setContactorId(contactorId);
                contactorBalanceAccountInfo.setContactorName(contactorBalanceAccountPo.getContactorName());
                BigDecimal contactorBalanceAmount = contactorBalanceAccountPo.getBalanceAmount();
                contactorBalanceAccountInfo.setContactorBalanceAmount(contactorBalanceAmount);//联系人账户余额
            } else {
                throw new HMYRuntimeException(506800004);
            }
            if (contactorsTotalArrearsAmountDos.stream().anyMatch(c -> c.getContactorId().equals(contactorId))) {
                BigDecimal totalReceivableAmount = contactorsTotalArrearsAmountDos.stream().filter(c -> c.getContactorId().equals(contactorId)).findFirst().get().getTotalReceivableAmount();
                contactorBalanceAccountInfo.setCustomerContractTotalArrearsAmount(totalReceivableAmount);//联系人合同总欠款金额
            } else {
                throw new HMYRuntimeException(506800005);
            }
            contactorBalanceAccountInfos.add(contactorBalanceAccountInfo);
        });

        response.setContactorBalanceAccountInfos(contactorBalanceAccountInfos);
        log.info("CustomerContactorBalanceAccountService#queryCustomerContactorBalanceAccountInfo response:{}", JSON.toJSON(response));
        return response;
    }

    @Override
    public ContactorInitialAccountRdto initialCustomerContactorBalanceAccount(ContactorInitialAccountDto contactorInitialAccountDto) {
        // check Customer Contactor Balance Account Exist
        CustomerContactorBalanceAccountPo contactorBalanceAccount = customerContactorBalanceAccountMapper.selectById(contactorInitialAccountDto.getContactorId());
        if (Objects.nonNull(contactorBalanceAccount)) {
            ContactorInitialAccountRdto contactorInitialAccountRdto = new ContactorInitialAccountRdto();
            contactorInitialAccountRdto.setContactorId(contactorInitialAccountDto.getContactorId());
            contactorInitialAccountRdto.setResult(true);
            contactorInitialAccountRdto.setMessage("Customer Contactor Balance Account Exist");
            return contactorInitialAccountRdto;
        }
        // before initialize Customer Contactor Balance Account, check Customer Balance Account Exist
        CustomerInitialAccountDto customerInitialAccountDto = new CustomerInitialAccountDto();
        customerInitialAccountDto.setCustomerId(contactorInitialAccountDto.getCustomerId());
        customerInitialAccountDto.setCustomerName(contactorInitialAccountDto.getCustomerName());
        customerInitialAccountDto.setAmount(BigDecimal.ZERO);
        CustomerInitialAccountRdto customerInitialAccountRdto = customerBalanceAccountProvideService.initialCustomerBalanceAccount(customerInitialAccountDto);
        if (!customerInitialAccountRdto.isSuccess()) {
            throw new HMYRuntimeException(506400001);
        }
        // Initial Customer Contactor Balance Account
        contactorBalanceAccount = new CustomerContactorBalanceAccountPo();
        contactorBalanceAccount.setBalanceAmount(contactorInitialAccountDto.getAmount());
        contactorBalanceAccount.setContactorId(contactorInitialAccountDto.getContactorId());
        contactorBalanceAccount.setCustomerId(contactorInitialAccountDto.getCustomerId());
        contactorBalanceAccount.setIsDeleted(0);
        contactorBalanceAccount.setCustomerName(contactorInitialAccountDto.getCustomerName());
        contactorBalanceAccount.setContactorName(contactorInitialAccountDto.getContactorName());
        contactorBalanceAccount.setAccountStatus(AccountStatusEnum.NORMAL);
        contactorBalanceAccount.setCreateTime(LocalDateTime.now());
        contactorBalanceAccount.setUpdateTime(LocalDateTime.now());
        contactorBalanceAccount.setCreatorId(-1L);
        contactorBalanceAccount.setUpdaterId(-1L);
        contactorBalanceAccount.setCreatorName("system");
        contactorBalanceAccount.setUpdaterName("system");
        log.info("CustomerContactorBalanceAccountService#initialCustomerContactorBalanceAccount request:{}", JSON.toJSON(contactorInitialAccountDto));
        int inserted = customerContactorBalanceAccountMapper.insert(contactorBalanceAccount);
        if (inserted <= 0) {
            throw new HMYRuntimeException(506800007);
        }
        ContactorInitialAccountRdto contactorInitialAccountRdto = new ContactorInitialAccountRdto();
        contactorInitialAccountRdto.setContactorId(contactorInitialAccountDto.getContactorId());
        contactorInitialAccountRdto.setResult(true);
        contactorInitialAccountRdto.setMessage("Initial Customer Contactor Balance Account Success");
        log.info("CustomerContactorBalanceAccountService#initialCustomerContactorBalanceAccount response:{}", JSON.toJSON(contactorInitialAccountRdto));
        return contactorInitialAccountRdto;
    }

    @Override
    public ContactorBalanceQueryRdto queryContactorBalance(ContactorBalanceQueryDto contactorBalanceQueryDto) {
        CustomerContactorBalanceAccountPo contactorBalanceAccount = customerContactorBalanceAccountMapper.selectById(contactorBalanceQueryDto.getContactorId());
        if (Objects.nonNull(contactorBalanceAccount)) {
            ContactorBalanceQueryRdto contactorBalanceQueryRdto = new ContactorBalanceQueryRdto();
            contactorBalanceQueryRdto.setCustomerId(contactorBalanceAccount.getCustomerId());
            contactorBalanceQueryRdto.setContactorId(contactorBalanceAccount.getContactorId());
            contactorBalanceQueryRdto.setContactorBalanceAmount(contactorBalanceAccount.getBalanceAmount());
            CustomerBalanceQueryDto customerBalanceQueryDto = new CustomerBalanceQueryDto();
            customerBalanceQueryDto.setCustomerId(contactorBalanceAccount.getCustomerId());
            CustomerBalanceQueryRdto customerBalanceQueryRdto = customerBalanceAccountProvideService.queryCustomerBalance(customerBalanceQueryDto);
            if (Objects.nonNull(customerBalanceQueryRdto)) {
                contactorBalanceQueryRdto.setCustomerBalanceAmount(customerBalanceQueryRdto.getBalanceAmount());
            }
            return contactorBalanceQueryRdto;
        }
        return null;
    }
}




